import json
from collections import OrderedDict
from pprint import pprint

from django import http
from django.core.paginator import Paginator, EmptyPage
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import GoodsChannel, GoodsCategory, SKU
from apps.goods.utils import get_breadcrumb
from apps.orders.models import OrderGoods
from utils import contents
from utils.get_category import get_categories
from utils.response_code import RETCODE
from utils.views import LoginRequiredJsonMixin


class ListView(View):
    def get(self, request, category_id, page_num):

        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseNotFound('参数category_id不存在')

        categories_dict = get_categories()

        breadcrumb = get_breadcrumb(category)

        sort = request.GET.get('sort', 'default')

        if sort == 'price':
            sort_field = 'price'
        elif sort == 'hot':
            sort_field = '-sales'
        else:
            sort = 'default'
            sort_field = 'create_time'

        skus = SKU.objects.filter(spu__category3=category, is_launched=True).order_by(sort_field)

        paginator = Paginator(skus, contents.GOODS_LIST_LIMIT)

        try:
            page_skus = paginator.page(page_num)
        except EmptyPage:
            return http.HttpResponseNotFound('empty page')

        total_page = paginator.num_pages

        context = {
            'categories': categories_dict,
            'breadcrumb': breadcrumb,
            'category': category,
            'sort': sort,
            'page_skus': page_skus,
            'total_page': total_page,
            'page_num': page_num
        }

        return render(request, 'list.html', context=context)


class HotGoodsView(View):
    def get(self, request, category_id):
        skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]

        hot_skus = []
        for sku in skus:
            hot_skus.append({
                'id': sku.id,
                'default_image_url': sku.default_image,
                'name': sku.name,
                'price': sku.price
            })

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})


class DetailView(View):
    def get(self, request, sku_id):

        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return render(request, '404.html')

        categories = get_categories()
        category = sku.spu.category3

        breadcrumb = get_breadcrumb(category)

        spu_spec_dict = {}
        all_skus = sku.spu.sku_set.all()
        for sku_temp in all_skus:
            one_sku_specs = sku_temp.specs.all()
            for one_sku_spec in one_sku_specs:
                if (one_sku_spec.spec.name, one_sku_spec.option.value) not in spu_spec_dict:
                    spu_spec_dict[(one_sku_spec.spec.name, one_sku_spec.option.value)] = {sku_temp.id}
                else:
                    spu_spec_dict[(one_sku_spec.spec.name, one_sku_spec.option.value)].add(sku_temp.id)

        pprint(spu_spec_dict)

        for op, val in spu_spec_dict.items():
            if sku.id in val:
                set_temp = val - {sku.id}
                spu_spec_dict[op] = {sku.id}
                for op2, val2 in spu_spec_dict.items():
                    for sku_id in set_temp:
                        if sku_id in val2:
                            spu_spec_dict[op2] = {sku_id}

        pprint(spu_spec_dict)

        spu_options = {}
        for op, val in spu_spec_dict.items():
            if op[0] not in spu_options:
                spu_options[op[0]] = [(op[1], val.pop())]
            else:
                spu_options[op[0]].append((op[1], val.pop()))

        pprint(spu_options)

        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'specs': spu_options
        }

        return render(request, 'detail.html', context=context)


class UserBrowseHistory(LoginRequiredJsonMixin, View):
    def post(self, request):
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')

        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.HttpResponseBadRequest('sku不存在')

        redis_conn = get_redis_connection('history')
        pl = redis_conn.pipeline()
        user_id = request.user.id

        pl.lrem('history_%s' % user_id, 0, sku_id)
        pl.lpush('history_%s' % user_id, sku_id)
        pl.ltrim('history_%s' % user_id, 0, 4)

        pl.execute()

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})

    def get(self, request):
        redis_conn = get_redis_connection('history')
        sku_ids = redis_conn.lrange('history_%s' % request.user.id, 0, -1)

        skus = []
        for sku_id in sku_ids:
            sku = SKU.objects.get(id=sku_id)
            skus.append({
                'id': sku.id,
                'name': sku.name,
                'default_image_url': sku.default_image,
                'price': sku.price
            })

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'skus': skus})


class GoodsCommentView(View):
    def get(self, request, sku_id):
        order_goods_list = OrderGoods.objects.filter(sku_id=sku_id, is_commented=True)[:30]

        comment_list = []
        for order_goods in order_goods_list:
            username = order_goods.order.user.username,
            comment_list.append({
                'username': username[0] + '***' + username[-1] if order_goods.is_anonymous else username,
                'comment': order_goods.comment,
                'score': order_goods.score
            })
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'comment_list': comment_list})
